#include "stdafx.h"
#include "DirectShow.h"

#define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }

CDirectShow::CDirectShow( HWND hWnd ): m_hWnd( hWnd ), m_bIsLoop( FALSE )
{
	pGraph = NULL;
	pMediaControl = NULL;
	pVidWin = NULL;
	pEvent = NULL;
}

CDirectShow::~CDirectShow()
{
	Destroy();
}

void CDirectShow::Open(char* szFile, int window_mode)
{
    //CoInitialize(NULL);

	WCHAR wFile[MAX_PATH];
    MultiByteToWideChar( CP_ACP, 0, szFile, -1, wFile, MAX_PATH );

    // Create the filter graph manager and render the file.
    CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC, IID_IGraphBuilder, (void **)&pGraph);
	pGraph->RenderFile(wFile, NULL);

    // Specify the owner window.
    pGraph->QueryInterface(IID_IVideoWindow, (void **)&pVidWin);
	pVidWin->put_WindowStyle(WS_CHILD | WS_CLIPSIBLINGS);
	pVidWin->put_Owner((OAHWND)m_hWnd);
	
    //event
    pGraph->QueryInterface(IID_IMediaEventEx, (void **)&pEvent);
	pEvent->SetNotifyWindow((OAHWND)m_hWnd, WM_VIDEOCHECK, 0);
	
	//static HWND hDrain=0;
	//pVidWin->get_MessageDrain((OAHWND *) &hDrain);
    // Set message drain to application main window
    pVidWin->put_MessageDrain((OAHWND)m_hWnd);
	// full screen 
	if(window_mode != 1)
	{
		int w = GetSystemMetrics(SM_CXSCREEN);
		int h = GetSystemMetrics(SM_CYSCREEN);


		pVidWin->SetWindowPosition(0, 0, w, h);
		pVidWin->put_FullScreenMode(OATRUE);
	}
	else
	{
		RECT client;
		GetClientRect(m_hWnd, &client);
		pVidWin->SetWindowPosition(client.left, client.top,  client.right, client.bottom);
	}

    //// Run the graph.
	pGraph->QueryInterface(IID_IMediaSeeking, (void **)&pSeeking);
    pGraph->QueryInterface(IID_IMediaControl, (void **)&pMediaControl);
    //pMediaControl->Run();
}

void CDirectShow::Play()
{
	LONGLONG cur = 0;

	if( pSeeking )
	{
		LONGLONG c, s;
		pSeeking->GetPositions(&c,&s);
		if( c != s && c!=0) return;
		pSeeking->SetPositions( &cur, AM_SEEKING_AbsolutePositioning, 0, AM_SEEKING_NoPositioning );
	}
	
	if( pMediaControl )
		pMediaControl->Run();
}
void CDirectShow::Stop()
{
	if( pSeeking )
		pMediaControl->Stop();
}




BOOL CDirectShow::IsEnd()
{
	if( pSeeking )
	{
		LONGLONG c, s;
		pSeeking->GetPositions(&c,&s);
		return c == s;
	}
	return TRUE;
}

void CDirectShow::Destroy(void)
{
	if( pVidWin )
	{
		pVidWin->SetWindowForeground(-1);
		pVidWin->put_Visible(OAFALSE);
		pVidWin->put_Owner(NULL);
		pVidWin->Release();
	}

    // Stop the graph.
	if( pMediaControl )pMediaControl->Stop();

    SAFE_RELEASE( pEvent );
    SAFE_RELEASE( pMediaControl );
    SAFE_RELEASE( pVidWin );
    SAFE_RELEASE( pGraph  );

//	CoUninitialize();
}

int CDirectShow::HandleEvent(void) 
{
	long evCode, param1, param2;
    HRESULT hr;
    while (hr = pEvent->GetEvent(&evCode, &param1, &param2, 0), SUCCEEDED(hr))
    { 
        hr = pEvent->FreeEventParams(evCode, param1, param2);
        if ((EC_COMPLETE == evCode) || (EC_USERABORT == evCode) )
        {
			Destroy();
			
			return 1;
        } 
    } 

	return -1;
}

void CDirectShow::Resize()
{
	if (pVidWin)
	{
		RECT client;
		GetClientRect(m_hWnd, &client);
		pVidWin->SetWindowPosition(client.left, client.top,  client.right, client.bottom);
	}
}

/////////////////////////////////////////////////////////////////////////////////////
